--[[
	author:	嵐朔雁@憤怒使者<神樣>
	ref: LFGForwarder
]]
-- debug switch --
GLF_DEBUG_ENABLED = false;

-- global --
GLF_LOCALE = {}; 												-- 語系
GLF_GLOBAL = {};
GLF_GLOBAL.Version = 0.1;
GLF_GLOBAL.GuildName = "神樣"
GLF_GLOBAL.PlayerName = UnitName("player");
GLF_GLOBAL.ChannelName="GLForwarder"..GLF_GLOBAL.GuildName;
GLF_GLOBAL.ChannelP="l1ll1l1lIl1IlII1Illl";
GLF_GLOBAL.KnownMaxVersion = GLF_GLOBAL.Version; 				-- 先初始化為目前Version
GLF_GLOBAL.ChatChannelColor = {r=0.5, g=1, b=0.5};

-- if (GLF_GLOBAL.PlayerName=="嵐朔雁" or GLF_GLOBAL.PlayerName=="烏漆漆") then
	-- GLF_DEBUG_ENABLED = true;
-- end;	

-- 語系，預設為繁體 --
local L = GLF_LOCALE
if(GetLocale() == "zhTW") then
	L["DESC"] = GLF_GLOBAL.GuildName.."公會頻道轉發, |cffff6aac嵐朔雁|cffb71717@憤怒使者|r<|cff68ccef神樣|r>"
	L["ChannelPrefix"] = "|cffff6aac"..GLF_GLOBAL.GuildName.."|r"; -- 頻道前綴
end;

-- 事件註冊
local frame = CreateFrame("Frame");
frame:RegisterEvent("PLAYER_ENTERING_WORLD");
frame:RegisterEvent("CHAT_MSG_CHANNEL");	-- For UI Channel
frame:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE_USER");
frame:RegisterEvent("CHAT_MSG_CHANNEL_LEAVE");
frame:RegisterEvent("CHAT_MSG_GUILD");
frame:RegisterEvent("CHAT_MSG_GUILD_ACHIEVEMENT");
--frame:RegisterEvent("GUILD_NEWS_UPDATE");
frame:RegisterEvent("GUILD_MOTD");
frame:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE");
frame:RegisterEvent("GROUP_ROSTER_UPDATE");

-- DEBUG Message
local function DBG(msg, r, g, b)
	if(GLF_DEBUG_ENABLED) then
		ChatFrame1:AddMessage(msg, r or 0.6, g or 0.6, b or 0.6);
	end
end

local State = 
{	
	InGuild = false;
	UIChannelNumber = nil;	-- 主要用此來判斷是否在UIChannel
	IsOwner = false;
	CurrentOwner = nil;	
	DefaultLanguage = GetDefaultLanguage("player");
};

local Command = 
{
	JOIN = "^@GLF_J";
	IN_GUILD_QUERY = "^@GLF_IGQ";
	IN_GUILD_NOTIFY = "^@GLF_IGN";
	
	-- sender, message, color
	-- _$為分隔
	GLF_CHAT_MSG_PATTERN = "^@GLF_C_$%s_$%s_$%s$"; 
	GLF_CHAT_MSG_FIND_PATTERN = "^%^@GLF_C_%$(.+)_%$(.+)_%$(%x%x%x%x%x%x)%$$";
};

local function SendCmd(cmd)
	DBG('SendCmd: '..cmd);
	if State.UIChannelNumber then
		pcall(SendChatMessage, cmd, "CHANNEL", State.DefaultLanguage, State.UIChannelNumber);
	end;
end;


local function EncodeAndSendMessage(sender, message, color)
	local encoded_str;
	if color then
		encoded_str=string.format(Command.GLF_CHAT_MSG_PATTERN, sender, message, color);
	else
		encoded_str=string.format(Command.GLF_CHAT_MSG_PATTERN, sender, message);
	end;
	SendCmd(encoded_str);
end;

local Timer =
{
	-- 檢查是否在UIChannel
	KeepInUIChannelTimer =
	{
		Inteval = 5;			-- seconds
		UIChannelJoinCheck = 5; -- 初始化為Inteval
		Tick = function(self, elapsed)	
			self.UIChannelJoinCheck = self.UIChannelJoinCheck - elapsed;
			if self.UIChannelJoinCheck <= 0 then
				JoinTemporaryChannel(GLF_GLOBAL.ChannelName, GLF_GLOBAL.ChannelP);
				self.UIChannelJoinCheck = self.Inteval;
			end;
		end;
	};
	
	-- 檢查是否需要交出Owner
	HandOverOwnerCheckTimer =
	{
		IsEnabled = false;
		Inteval=5;
		Check=5;
		Tick = function(self, elapsed)
			if self.IsEnabled~=true then 
				return 
			end;
			self.Check=self.Check-elapsed;	
			if self.Check<=0 then
				SendCmd(Command.IN_GUILD_QUERY);
				self.Check=Inteval;
			end;
		end;
	};	
};

local Utils =
{
	--[[
		@desc	Check if player in target guild
	]]
	SetInGuildState = function(self)
		local guildName = select(1, (GetGuildInfo("player")));
		if guildName == GLF_GLOBAL.GuildName then
			State.InGuild=true;
		end
	end;
	--[[
		@desc 頻道是一個List: 1 綜合 3 本地防務...
		目前沒有使用，改讀取Event內傳回的頻道編號
	]]
	GetGLFChannelNumber = function (self)
		local channels = {GetChannelList()}
		for i=2, #channels, 2 do			
			if(channels[i]==GLF_GLOBAL.ChannelName) then					
				return channels[i-1]; -- 編號在前一個
			end;
		end;		
		return nil;
	end;
	
	GetClassColorByGUID = function (self, guid)
		local _, englishClass, _, _, _ = GetPlayerInfoByGUID(guid)
		local color = string.format("%.2x%.2x%.2x", 255, 255, 0);
		if ( englishClass ) then
			local classColorTable = RAID_CLASS_COLORS[englishClass];
			if ( classColorTable ) then
				color = string.format("%.2x%.2x%.2x", classColorTable.r*255, classColorTable.g*255, classColorTable.b*255)
			end
		end
		return color;
	end;	
	
	-- QueryUIChannelOwnerAndNumberAsync
	QueryUIChannelOwnerAndNumberAsync = function(self)
		DisplayChannelOwner(GLF_GLOBAL.ChannelName)
	end;	
	QueryUIChannelOwnerAndNumberAsyncCompleted = function(self, sender, channelNumber)
		-- 更新State
		State.UIChannelNumber = channelNumber;
		State.CurrentOwner = sender;
		if State.CurrentOwner == GetUnitName('player') then
			State.IsOwner = true;
		end;
		
		-- 是否在公會內狀態要在這裡更新，因為 PLAYER_ENTERING_WORLD 這個事件太早取不到公會資訊
		self:SetInGuildState();
		
		-- 需要轉出Owner
		if State.IsOwner==true and State.InGuild==false then
			DBG('Start HandOverOwnerCheckTimer');
			Timer.HandOverOwnerCheckTimer.IsEnabled=true;
		end;
	end;
};

--[[
	命令
]]
SLASH_GLF1 = "/godlikeforwarder";
SLASH_GLF2 = "/glf";
SlashCmdList["GLF"] = function(cmd)
	if string.len(cmd) == 0 then
		DEFAULT_CHAT_FRAME:AddMessage(L["DESC"]);
	elseif cmd == 'debug' then
		GLF_DEBUG_ENABLED = not GLF_DEBUG_ENABLED;
		DEFAULT_CHAT_FRAME:AddMessage("DebugSwitch="..tostring(GLF_DEBUG_ENABLED))
	elseif cmd == 'state' then
		DEFAULT_CHAT_FRAME:AddMessage("=========================================")
		DEFAULT_CHAT_FRAME:AddMessage("DebugSwitch="..tostring(GLF_DEBUG_ENABLED))
		DEFAULT_CHAT_FRAME:AddMessage("InGuild="..tostring(State.InGuild))
		DEFAULT_CHAT_FRAME:AddMessage("IsOwner="..tostring(State.IsOwner))
		DEFAULT_CHAT_FRAME:AddMessage("CurrentOwner="..State.CurrentOwner)
		DEFAULT_CHAT_FRAME:AddMessage("UIChannelNumber="..tostring(State.UIChannelNumber))
		DEFAULT_CHAT_FRAME:AddMessage("=========================================")
	end;
end;

----------------------------------------------------------
-- Deal Cmd and Forwarded messages
----------------------------------------------------------
local SLURRED_SPEECH_REMOVE = string.gsub(SLURRED_SPEECH, "%%s", "(.+)").."$"	-- 移掉喝醉酒打嗝字串
local function GLF_OnUIMessage(message, sender, guid, counter)
	message = string.gsub(message, SLURRED_SPEECH_REMOVE, "%1");

	if message==Command.JOIN then

	elseif message==Command.IN_GUILD_QUERY then
		if State.InGuild==true then
			SendCmd(Command.IN_GUILD_NOTIFY);
		end;

	elseif message==Command.IN_GUILD_NOTIFY then
		if State.IsOwner then
			Timer.HandOverOwnerCheckTimer.IsEnabled=false; --停止轉交Owner Timer
			--轉交Owner，State資訊會在event中更新
			SetChannelOwner(GLF_GLOBAL.ChannelName, sender);
		end;
	else	
	
		if(ChatLink_Decompose) then message = ChatLink_Decompose(message) end;
		
		
		if State.InGuild~=true then	
			-- 對話、成就
			local IsMatch, _, name, msg, color = strfind(message, Command.GLF_CHAT_MSG_FIND_PATTERN);		
			if IsMatch then	
							
					local output = string.format("[神樣]|Hplayer:%s:%d|h[|cff%s%s|r]: %s", name, counter, color, name, msg);
					DEFAULT_CHAT_FRAME:AddMessage(
						output, 
						GLF_GLOBAL.ChatChannelColor.r, 
						GLF_GLOBAL.ChatChannelColor.g, 
						GLF_GLOBAL.ChatChannelColor.b);
					
			else
				-- 對話格式有問題
			end;
		end;	
	end;
end;

frame:SetScript("OnEvent", 
function(self,event,...)
	if (event=="PLAYER_ENTERING_WORLD") then
		if(L["DESC"]) then DEFAULT_CHAT_FRAME:AddMessage(L["DESC"]) end

		-- 嘗試取得頻道擁有者與頻道編號 主要是Reload時候使用
		Utils:QueryUIChannelOwnerAndNumberAsync();

		self:UnregisterEvent("PLAYER_ENTERING_WORLD");
	
	--[[
		message: YOU_JOINED、YOU_LEFT、SUSPENDED
		剛上線時最先知道頻道編號的地方
	]]
	elseif (event=="CHAT_MSG_CHANNEL_NOTICE") then
		local message, sender, language, channelString, target, flags, _, channelNumber, channelName, _, counter = ...;
		if channelName ~= GLF_GLOBAL.ChannelName then return end
		DBG("===CHAT_MSG_CHANNEL_NOTICE===");
		DBG("message: "..message);
		DBG("sender: "..sender);
		DBG("channelString: "..channelString);
		DBG("counter: "..counter);
		
		if message == "YOU_JOINED" then
			Utils:QueryUIChannelOwnerAndNumberAsync();			
		end;
		
	elseif (event=="CHAT_MSG_CHANNEL_NOTICE_USER") then
		local message, sender, language, channelString, target, flags, _, channelNumber, channelName, _, counter = ...;
		if channelName ~= GLF_GLOBAL.ChannelName then return end
		DBG("===CHAT_MSG_CHANNEL_NOTICE_USER===");
		DBG("message: "..message);
		DBG("sender: "..sender);
		DBG("channelNumber: "..channelNumber);
		DBG("counter: "..counter);
		
		-- 下QueryUIChannelOwnerAndNumberAsync後回應的地方，取得ChannelNumber與ChannelOwer
		if(message=="CHANNEL_OWNER") then
			Utils:QueryUIChannelOwnerAndNumberAsyncCompleted(sender, channelNumber);
			
		elseif(message=="PLAYER_NOT_FOUND") then
		
		-- 要判斷是否OWNER丟到自己身上，且此時不在公會內
		elseif(message=="OWNER_CHANGED") then
			Utils:QueryUIChannelOwnerAndNumberAsync();
		
		elseif(message=="PASSWORD_CHANGED") then
		elseif(message=="PLAYER_KICKED") then
		elseif(message=="PLAYER_BANNED") then
		elseif(message=="PLAYER_NOT_BANNED") then
		elseif(message=="PLAYER_UNBANNED") then
		end;
		
	elseif(event=="CHAT_MSG_CHANNEL_LEAVE") then
		local _, sender, _, channelString, _, _, _, channelNumber, channelName, _, _ = ...;
		if channelName ~= GLF_GLOBAL.ChannelName then return end
		DBG("===CHAT_MSG_CHANNEL_LEAVE===");
		DBG("sender: "..sender);
		DBG("channelString: "..channelString);
		
		UIChannelNumber = nil;
		
	-- UI頻道對話事件
	elseif(event=="CHAT_MSG_CHANNEL") then
		local message, sender, language, channelString, target, flags, _, channelNumber, channelName, _, counter, guid = ...;
		if channelName ~= GLF_GLOBAL.ChannelName then return end
		
		GLF_OnUIMessage(message, sender, guid, counter);
		
	---------------------------------------------------------------
	--	公會事件
	---------------------------------------------------------------
	-- 公會對話事件
	elseif(event=="CHAT_MSG_GUILD") then
		local message, sender, language, channelString, target, flags, _, channelNumber, channelName, _, counter, guid = ...;	
		if State.IsOwner then
		--	EncodeAndSendMessage(sender, message, Utils:GetClassColorByGUID(guid));	
		end;
	
	-- 公會成就事件
	elseif(event=="CHAT_MSG_GUILD_ACHIEVEMENT") then
		local message, sender, language, channelString, target, flags, _, channelNumber, channelName, _, counter, guid = ...;
		if State.IsOwner then
		--	EncodeAndSendMessage(sender, string.format(message,sender), Utils:GetClassColorByGUID(guid));
		end;
	
	elseif(event=="GUILD_MOTD") then
		local message = ...;
		DBG("===GUILD_MOTD===");
		DBG("message: "..(message or ""));
	end
end
);

-- Delay加入UI Channel的時間
frame:SetScript("OnUpdate", 
	function(self, elapsed) -- elapse表與上一個Update的間隔秒數
		Timer.KeepInUIChannelTimer:Tick(elapsed);
		Timer.HandOverOwnerCheckTimer:Tick(elapsed);
	end
);

-- ChatFrame Filter
function GLF_FilterIncoming(self, event, ...)
	local message, sender, language, channelString, target, flags, channelIdx, channelNumber, channelName, _, counter, guid = ...;
	if channelName ~= GLF_GLOBAL.ChannelName then return end	
	
	
	return true;
end;
ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", GLF_FilterIncoming);
ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL_NOTICE_USER", GLF_FilterIncoming); -- 隱藏加入頻道訊息
